class ModelBuilder:
    def __init__(self):
        self.rule = None
        self.root = None
        self.struct = None

    def loads(self, jsond):
        self.rule = json.loads(jsond)
        self.root = self.rule['struct'][0]
        self.struct = self.rule['struct']

    def build(self):
        if self.rule != None:
            check = (self.root['name'] == 'root')
            node_name = {}
            for node in self.struct:
                node_name[node['name']] = -1
            for node in self.struct:
                node_name[node['name']] += 1
            check &= (sum([node_name[x] for x in node_name]) == 0)
            if not check:
                raise Exception("结构语法错误")
            else:
                self._build(self.root)
            build_result = []
            for node in self.struct:
                if len(node['buttom']) == 0:
                    build_result.append(node)
            return self.struct
        #             return build_result
        else:
            raise Exception('语法结构错误')

    def find_node(self, node_name):
        rnode = None
        for index, node in enumerate(self.struct):
            if self.struct[index]['name'] == node_name:
                rnode = node
                return rnode
        if rnode == None:
            raise Exception("未知的节点")

    def _build(self, node):
        if node == None:
            print(node)
        node['compiled'] = False
        node['compile'] = globals()[node['type']]
        for child_name in node['buttom']:
            child = self.find_node(child_name)
            self._build(child)

    def compile(self):
        self._compile(self.root, None)
        return self.struct

    def _compile(self, node, father):
        node['p_above'] = []
        if father != None:
            node['p_above'].append(father['compile'])
            print(node['compile'])
        if node['compiled'] == False:
            node['compile'] = node['compile'](node['name'])
        node['compiled'] = True
        for child_name in node['buttom']:
            child = self.find_node(child_name)
            self._compile(child, node)
